home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / DIAGXPRT.PAK / DIAGXPRT.CPP < prev    next >
C/C++ Source or Header  |  1997-05-06  |  15KB  |  666 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // (C) Copyright 1993, 1995 by Borland International, All Rights Reserved
  4. //
  5. //----------------------------------------------------------------------------
  6. #include <owl/pch.h>
  7. #include <owl/serialze.h>
  8. #include <winsys/system.h>
  9. #include "diagxprt.h"
  10. #include "setup.h"
  11.  
  12. #include <toolhelp.h>
  13. #include <iostream.h>
  14. #include <cstring.h>
  15. #include <stdio.h>
  16.  
  17. #include "diagxprt.rh"
  18.  
  19. //----------------------------------------------------------------------------
  20. //
  21. //  class TDiagClient
  22. //
  23.  
  24. DEFINE_RESPONSE_TABLE1(TDiagClient, TEditFile)
  25.   EV_COMMAND(CM_FILENEW, CmFileNew),
  26.   EV_COMMAND(CM_FILEOPEN, CmFileOpen),
  27.   EV_COMMAND(CM_FILESAVE, CmFileSave),
  28.   EV_COMMAND(CM_FILESAVEAS, CmFileSaveAs),
  29.   EV_COMMAND(CM_SETUP, CmSetup),
  30.   EV_COMMAND(CM_START, CmStart),
  31.   EV_COMMAND(CM_STOP, CmStop),
  32.   EV_COMMAND(CM_MEM, CmMem),
  33.   EV_COMMAND(CM_HELP, CmHelp),
  34.   EV_COMMAND_ENABLE(CM_FILENEW, CmFileNewEnable),
  35.   EV_COMMAND_ENABLE(CM_FILEOPEN, CmFileOpenEnable),
  36.   EV_COMMAND_ENABLE(CM_FILESAVE, CmFileSaveEnable),
  37.   EV_COMMAND_ENABLE(CM_SETUP, CmSetupEnable),
  38.   EV_COMMAND_ENABLE(CM_START, CmStartEnable),
  39.   EV_COMMAND_ENABLE(CM_STOP, CmStopEnable),
  40.   EV_MESSAGE(CM_LOGPARAMERROR, CmLogParamError),
  41.   EV_MESSAGE(CM_LOGERROR, CmLogError),
  42.   EV_MESSAGE(CM_OUTSTR, CmOutStr),
  43. //  EV_MESSAGE(CM_DEFAULT, CmDefault),  // Will display unhandled toolhelp ids
  44. END_RESPONSE_TABLE;
  45.  
  46. //
  47. //
  48. //
  49. TDiagClient* TDiagClient::pThis;
  50.  
  51. //
  52. //
  53. //
  54. void
  55. TDiagClient::CmStart()
  56. {
  57.   nActive = 1;
  58. }
  59.  
  60. //
  61. //
  62. //
  63. void
  64. TDiagClient::CmStop()
  65. {
  66.   nActive = 0;
  67. }
  68.  
  69. //
  70. //
  71. //
  72. void
  73. TDiagClient::CmSetup()
  74. {
  75.   nActive--;
  76.   TSetupDialog(this).Execute();
  77.   nActive++;
  78. }
  79.  
  80. //
  81. //
  82. //
  83. static char* helpText[] = {
  84.   "DIAGXPRT displays diagnostic messages sent by OutputDebugString()",
  85.   "or by the RTL diagnostic macros, TRACEX & WARNX.",
  86.   "OWL diagnostics can be enabled or disabled by using the configure button.",
  87.   "There are two levels of diagnostics used in OWL, 0 and 1.  You can configure",
  88.   "this for each area.",
  89.   "You can also add your own diagnostic groups.  Each new group will be",
  90.   "written to the OWL.INI file and the declaration placed on the clipboard",
  91.   "for inclusion in your code.",
  92.   "The OWL.INI file is only read when your application loads.",
  93.   "Please see the RTL documentation and online help for a complete description",
  94.   "of the diagnostic macros and their use.  You may also look in OWL source",
  95.   "for additional examples.",
  96.   0
  97. };
  98.  
  99. //
  100. //
  101. //
  102. void
  103. TDiagClient::CmHelp()
  104. {
  105.   SetSelection(-1, -1);
  106.  
  107.   for (int i = 0; helpText[i]; i++) {
  108.     Insert(helpText[i]);
  109.     Insert("\r\n");
  110.   }
  111. }
  112.  
  113. //
  114. // Dumps memory statistics into output window
  115. //
  116. void
  117. TDiagClient::CmMem()
  118. {
  119.   static char buf[80];
  120.  
  121.   MEMMANINFO info;
  122.   info.dwSize=sizeof(info);
  123.  
  124.   SYSHEAPINFO sysInfo;
  125.   sysInfo.dwSize=sizeof(sysInfo);
  126.  
  127.   SetSelection(-1, -1);
  128.  
  129.   Insert("Compacting heap, please wait\r\n");
  130.  
  131.   DWORD freeMemEst = GlobalCompact(-1);
  132.   sprintf(buf,"Estimated free memory = %lu\r\n",freeMemEst);
  133.   Insert(buf);
  134.  
  135.   if (!TSystem::IsWin95() && MemManInfo(&info)) {
  136.     Insert("MemManInfo() reports...\r\n");
  137.     sprintf(buf,"..Largest free block = %lu\r\n", info.dwLargestFreeBlock);
  138.     Insert(buf);
  139.     sprintf(buf,"..Max pages available = %lu\r\n", info.dwMaxPagesAvailable);
  140.     Insert(buf);
  141.     sprintf(buf,"..Max pages lockable = %lu\r\n", info.dwMaxPagesLockable);
  142.     Insert(buf);
  143.     sprintf(buf,"..Total linear space = %lu\r\n", info.dwTotalLinearSpace);
  144.     Insert(buf);
  145.     sprintf(buf,"..Total unlocked pages = %lu\r\n", info.dwTotalUnlockedPages);
  146.     Insert(buf);
  147.     sprintf(buf,"..Free pages = %lu\r\n", info.dwFreePages);
  148.     Insert(buf);
  149.     sprintf(buf,"..Total pages = %lu\r\n", info.dwTotalPages);
  150.     Insert(buf);
  151.     sprintf(buf,"..Free linear space = %lu\r\n", info.dwFreeLinearSpace);
  152.     Insert(buf);
  153.     sprintf(buf,"..Swap file pages = %lu\r\n", info.dwSwapFilePages);
  154.     Insert(buf);
  155.     sprintf(buf,"..Page size = %u\r\n",  info.wPageSize);
  156.     Insert(buf);
  157.   }
  158.   else
  159.     Insert("MemManInfo() failed\r\n");
  160.  
  161.   if (SystemHeapInfo(&sysInfo)) {
  162.     Insert("SysHeapInfo() reports...\r\n");
  163.     sprintf(buf,"..User free percent = %u\r\n", sysInfo.wUserFreePercent);
  164.     Insert(buf);
  165.     sprintf(buf,"..GDI free percent = %u\r\n", sysInfo.wGDIFreePercent);
  166.     Insert(buf);
  167.   }
  168.   else
  169.     Insert("SysHeapInfo() failed\r\n");
  170. }
  171.  
  172. //
  173. // Override of TEditFile::CanClear()
  174. //
  175. bool
  176. TDiagClient::CanClear()
  177. {
  178.   // We don't want to be prompted all the time to see if we want to save the
  179.   // text
  180.   //
  181.   return true;
  182. }
  183.  
  184. //
  185. //
  186. //
  187. void
  188. TDiagClient::SetupWindow()
  189. {
  190.   TEditFile::SetupWindow();
  191.   nActive = 0;
  192.   pThis = this;
  193.   pThunk = MakeProcInstance(FARPROC(Callback), *GetModule());
  194.  
  195.   // Create 2 fonts: A big one and a small one. Names & sizes are loaded
  196.   // from resource file.
  197.   //
  198.   pFont0 = new TFont(
  199.     string(*GetModule(), IDS_FONT0_NAME).c_str(),
  200.     atoi(string(*GetModule(), IDS_FONT0_SIZE).c_str()));
  201.   pFont1 = new TFont(
  202.     string(*GetModule(), IDS_FONT1_NAME).c_str(),
  203.     atoi(string(*GetModule(), IDS_FONT1_SIZE).c_str()));
  204.  
  205.   SetSize(bigSize);
  206.   LoadMode();
  207.   NotifyRegister(0, (LPFNNOTIFYCALLBACK)pThunk, NF_NORMAL);
  208. }
  209.  
  210. //
  211. //
  212. //
  213. void
  214. TDiagClient::CleanupWindow()
  215. {
  216.   SaveMode();
  217.  
  218.   // Un-register our callback by toolhelp
  219.   //
  220.   NotifyUnRegister(0);
  221.   FreeProcInstance(pThunk);
  222.   delete pFont0;
  223.   delete pFont1;
  224. }
  225.  
  226. //
  227. //
  228. //
  229. void
  230. TDiagClient::SetSize(Size s)
  231. {
  232.   // Called when the frame window changes "size" (small or big). We make
  233.   // here the client window reflect the change by modifying some attributes
  234.   size = s;
  235.  
  236.   // Small font for smallSize, large font for bigSize
  237.   //
  238.   SetWindowFont(*(size == bigSize ? pFont0 : pFont1), true);
  239.  
  240.   // No scroll bar for smallSize, scroll bars for largeSize
  241.   //
  242.   Attr.Style = GetWindowLong(GWL_STYLE);
  243.   if (size == bigSize)
  244.     Attr.Style |= (WS_VSCROLL+WS_HSCROLL);
  245.   else
  246.     Attr.Style &= ~(WS_VSCROLL+WS_HSCROLL);
  247.   SetWindowLong(GWL_STYLE, Attr.Style);
  248. }
  249.  
  250. //
  251. //
  252. //
  253. void
  254. FixUpEOL(char *str)
  255. {
  256.   while (*str) {
  257.     // Normalize the \r\n ordering (edit doesn't tolerate \n\r)
  258.     //
  259.     if (str[0] == '\n') {
  260.       if (str[1] == '\r')
  261.         str[1] = '\n';
  262.       else
  263.         memmove(str+1,str,strlen(str)+1);
  264.       str[0] = '\r';
  265.       str += 2;
  266.     }
  267.     else
  268.       str++;
  269.   }
  270. }
  271.  
  272. //
  273. //
  274. //
  275. LRESULT
  276. TDiagClient::CmDefault(WPARAM id, LPARAM /*data*/)
  277. {
  278.   if (!nActive)
  279.     return true;
  280.  
  281.   char buf[128];
  282.   sprintf(buf,"Toolhelp callback id: %u\r\n",id);
  283.  
  284.   // To avoid beeing overflown: passed 200 lines, keep deleting
  285.   // the first line so that the number of lines cannot grow
  286.   //
  287.   if (GetNumLines() >= 200)
  288.     DeleteLine(0);
  289.  
  290.   // Append the line to display to the end of the edit buffer
  291.   //
  292.   SetSelection(-1, -1);
  293.   Insert(buf);
  294.   SetSelection(-1, -1);
  295.  
  296.   return true;
  297. }
  298.  
  299. //
  300. // This gets called as a result of a message post from the toolhelp
  301. // callback
  302. //
  303. LRESULT
  304. TDiagClient::CmOutStr(WPARAM /*id*/, LPARAM data)
  305. {
  306.   if (!nActive)
  307.     return true;
  308.  
  309.   // To avoid beeing overflown: passed 200 lines, keep deleting
  310.   // the first line so that the number of lines cannot grow
  311.   //
  312.   if (GetNumLines() >= 200)
  313.     DeleteLine(0);
  314.  
  315.   // Append the line to display to the end of the edit buffer
  316.   //
  317.   TDispData far* d = (TDispData far *)data;
  318.   SetSelection(-1, -1);
  319.   FixUpEOL(d->ProcName);
  320.   Insert(d->ProcName); // Really message
  321.  
  322.   // Assume that caller of OutputDebugString is responsible for \r\n
  323.   // Insert("\r\n");
  324.   //
  325.   SetSelection(-1, -1);
  326.  
  327.   // This was allocated in call back
  328.   //
  329.   delete d;
  330.   return true;
  331. }
  332.  
  333. //
  334. //
  335. //
  336. LRESULT
  337. TDiagClient::CmLogParamError(WPARAM /*id*/, LPARAM data)
  338. {
  339.   if (!nActive)
  340.     return true;
  341.  
  342.   TDispData far* d = (TDispData far *)data;
  343.   char buf[128];
  344.   FormatLogParamError(buf, sizeof(buf), d);
  345.  
  346.   // To avoid beeing overflown: passed 200 lines, keep deleting
  347.   // the first line so that the number of lines cannot grow
  348.   //
  349.   if (GetNumLines() >= 200)
  350.     DeleteLine(0);
  351.  
  352.   // Append the line to display to the end of the edit buffer
  353.   //
  354.   SetSelection(-1, -1);
  355.   Insert(buf);
  356.   SetSelection(-1, -1);
  357.  
  358.   delete d;
  359.   return true;
  360. }
  361.  
  362. //
  363. //
  364. //
  365. LRESULT
  366. TDiagClient::CmLogError(WPARAM /*id*/, LPARAM data)
  367. {
  368.   if (!nActive)
  369.     return true;
  370.  
  371.   TDispData far* d = (TDispData far*)data;
  372.   char buf[128];
  373.   FormatLogError(buf, sizeof(buf), d);
  374.  
  375.   // To avoid beeing overflown: passed 200 lines, keep deleting
  376.   // the first line so that the number of lines cannot grow
  377.   //
  378.   if (GetNumLines() >= 200)
  379.     DeleteLine(0);
  380.  
  381.   // Append the line to display to the end of the edit buffer
  382.   //
  383.   SetSelection(-1, -1);
  384.   Insert(buf);
  385.   SetSelection(-1, -1);
  386.  
  387.   delete d;
  388.   return true;
  389. }
  390.  
  391. //
  392. //
  393. //
  394. void
  395. TDiagClient::SaveMode()
  396. {
  397.   WritePrivateProfileString(DIAG_CLS, DIAG_MODE, nActive > 0 ? "1":"0", DIAG_INI);
  398. }
  399.  
  400. void
  401. TDiagClient::LoadMode()
  402. {
  403.   char b[4];
  404.   GetPrivateProfileString(DIAG_CLS, DIAG_MODE, "0", b, sizeof(b), DIAG_INI);
  405.   nActive = *b != '0';
  406. }
  407.  
  408. //----------------------------------------------------------------------------
  409. //
  410. //  class TDiagFrame
  411. //
  412.  
  413. DEFINE_RESPONSE_TABLE3(TDiagFrame, TTinyCaption, TDecoratedFrame, TSerializeReceiver)
  414.   EV_WM_SYSCOMMAND,
  415.   EV_WM_SIZE,
  416. END_RESPONSE_TABLE;
  417.  
  418. //
  419. //
  420. //
  421. TDiagFrame::TDiagFrame(const char* t, TWindow* c)
  422. :
  423.   TDecoratedFrame(0, t, c, true),
  424.   TTinyCaption(),
  425.   TWindow(0, t, 0)
  426. {
  427.   // This frame window is special. We start with a normal caption but are
  428.   // prepared to switch to a tiny caption...
  429.   //
  430.   Attr.Style = WS_OVERLAPPEDWINDOW & ~WS_VISIBLE;
  431.   EnableTinyCaption(44, false);
  432.   TCEnabled = false;
  433. }
  434.  
  435. //
  436. //
  437. //
  438. void
  439. TDiagFrame::SetupWindow()
  440. {
  441.   TDecoratedFrame::SetupWindow();
  442.  
  443.   // Add to the system menu a menu-item which can be used to switch
  444.   // to a tiny-caption and back to normal:
  445.   //
  446.   TSystemMenu Menu(*this);
  447.   Menu.InsertMenu(SC_CLOSE, MF_BYCOMMAND|MF_CHECKED, SC_TOGGLE_SIZE,
  448.                   string(*GetModule(), IDS_DECORATED).c_str());
  449.   Menu.InsertMenu(SC_CLOSE, MF_BYCOMMAND|MF_SEPARATOR, -1, 0);
  450.  
  451.   // Restore the window to size it had at the last session:
  452.   //
  453.   char b[20];
  454.   if (GetPrivateProfileString(DIAG_CLS, DIAG_RECT, "", b, sizeof(b), OWL_INI)) {
  455.     sscanf(b, "%d,%d,%d,%d", &rect.left, &rect.top, &rect.right, &rect.bottom);
  456.     MoveWindow(rect, true);
  457.   }
  458. }
  459.  
  460. //
  461. //
  462. //
  463. void
  464. TDiagFrame::CleanupWindow()
  465. {
  466.   TDecoratedFrame::CleanupWindow();
  467.  
  468.   // Remember the size for the next time:
  469.   //
  470.   char b[20];
  471.   sprintf(b, "%d,%d,%d,%d", rect.left, rect.top, rect.right, rect.bottom);
  472.   WritePrivateProfileString(DIAG_CLS, DIAG_RECT, b, OWL_INI);
  473. }
  474.  
  475. //
  476. //
  477. //
  478. void
  479. TDiagFrame::EvSize(uint type, TSize &size)
  480. {
  481.   TDecoratedFrame::EvSize(type, size);
  482.  
  483.   // We remember the size of the frame window whenever it changes.
  484.   // Note however that we are only interested by 'normal' resizes,
  485.   // not resizes dued to maximized or minimized operations.
  486.   //
  487.   if (type == SIZE_RESTORED)
  488.     rect = GetWindowRect();
  489. }
  490.  
  491. //
  492. //
  493. //
  494. LRESULT
  495. TDiagFrame::EvCommand(uint id, HWND hWndCtl, uint notifyCode)
  496. {
  497.   LRESULT er;
  498.  
  499.   // Give a chance to the TTinyCaption mixin to completely process the
  500.   // events it knows about:
  501.   //
  502.   if (TTinyCaption::DoCommand(id, hWndCtl, notifyCode, er) == esComplete)
  503.     return er;
  504.  
  505.   // Otherwise, forward to the frame window
  506.   //
  507.   return TFrameWindow::EvCommand(id, hWndCtl, notifyCode);
  508. }
  509.  
  510. //
  511. //
  512. //
  513. void
  514. TDiagFrame::EvSysCommand(uint id,TPoint& pt)
  515. {
  516.   switch (id) {
  517.     case SC_TOGGLE_SIZE:
  518.       // Here we are: the user selected the toggle menu-item
  519.       // from the system menu
  520.       CmToggleSize();
  521.       break;
  522.     default:
  523.       if (TTinyCaption::DoSysCommand(id, pt) == esPartial)
  524.         TFrameWindow::EvSysCommand(id, pt);
  525.   }
  526. }
  527.  
  528. //
  529. //
  530. //
  531. void
  532. TDiagFrame::CmToggleSize()
  533. {
  534.   TCEnabled ^= true;
  535.  
  536.   // Toggle the menu-item in the system menu
  537.   //
  538.   TSystemMenu Menu(*this);
  539.   uint bCheck = TCEnabled ? MF_UNCHECKED:MF_CHECKED;
  540.   Menu.CheckMenuItem(SC_TOGGLE_SIZE, MF_BYCOMMAND | bCheck);
  541.  
  542.   // Toggle the toolbar visibility
  543.   //
  544.   TDecoratedFrame::EvCommand(CM_TOOLBAR, 0, 0);
  545.  
  546.   // Toggle the status bar visibility
  547.   //
  548.   TDecoratedFrame::EvCommand(CM_STATUSBAR, 0, 0);
  549.  
  550.   // Notify the client that we want to toggle the size
  551.   //
  552.   TDiagClient *pClient = TYPESAFE_DOWNCAST(ClientWnd, TDiagClient);
  553.   CHECK(pClient != 0);
  554.   pClient->SetSize(TCEnabled ? TDiagClient::smallSize:TDiagClient::bigSize);
  555.  
  556.   // Force a calcsize by simulating a window resize
  557.   //
  558.   TRect rect = GetWindowRect();
  559.   rect.right--;
  560.   MoveWindow(rect, false);
  561.   rect.right++;
  562.   MoveWindow(rect, true);
  563. }
  564.  
  565. //
  566. //
  567. //
  568. void
  569. TDiagFrame::DataReceived(uint32 length, void* data)
  570. {
  571.   TEditFile* edit = TYPESAFE_DOWNCAST(GetClientWindow(), TEditFile);
  572.   if (edit) {
  573.     uint len = uint(length);
  574.     char* str = new char[len + 1];
  575.     strncpy(str, (char*)data, len);
  576.     str[len] = 0;
  577.     edit->SetSelection(-1, -1);
  578.     FixUpEOL(str);
  579.     edit->Insert((char*)str);
  580. //    edit->Insert("\r\n");
  581.     edit->SetSelection(-1, -1);
  582.     delete[] str;
  583.   }
  584. }
  585.  
  586. //----------------------------------------------------------------------------
  587. //
  588. //  class TOwlDiagApp
  589. //
  590.  
  591. //
  592. // This defines the icons for the speedbar
  593. //
  594. int TOwlDiagApp::speedbar[] = {
  595.   CM_FILENEW, CM_FILENEW,
  596.   CM_FILEOPEN, CM_FILEOPEN,
  597.   CM_FILESAVE, CM_FILESAVE,
  598.   CM_FILESAVEAS, CM_FILESAVEAS,
  599.   -1, -1,
  600.   CM_EDITCOPY, CM_EDITCOPY,
  601.   CM_EDITCUT, CM_EDITCUT,
  602.   CM_EDITPASTE, CM_EDITPASTE,
  603.   -1, -1,
  604.   CM_EDITFIND, CM_EDITFIND,
  605.   CM_EDITREPLACE, CM_EDITREPLACE,
  606.   CM_EDITFINDNEXT, CM_EDITFINDNEXT,
  607.   -1, -1,
  608.   CM_SETUP, CM_SETUP,
  609.   -1, -1,
  610.   IDB_START, CM_START,
  611.   IDB_STOP, CM_STOP,
  612.   -1, -1,
  613.   IDB_MEM,  CM_MEM,
  614.   IDB_HELP, CM_HELP,
  615.   0, 0
  616. };
  617.  
  618. //
  619. //
  620. //
  621. void
  622. TOwlDiagApp::InitMainWindow()
  623. {
  624.   TDiagFrame *frame = new TDiagFrame(
  625.     string(*this, IDS_TITLE).c_str(), new TDiagClient);
  626.  
  627.   TControlBar* cb = new TControlBar(frame);
  628.  
  629.   for (int *pID = speedbar; *pID; pID += 2) {
  630.     if (pID[0] == -1)
  631.       cb->Insert(*new TSeparatorGadget(6));
  632.     else
  633.       cb->Insert(*new TButtonGadget(pID[0], pID[1]));
  634.   }
  635.   cb->Attr.Id = CM_TOOLBAR;
  636.  
  637.   // Turn on control bar hints.
  638.   //
  639.   cb->SetHintMode(TGadgetWindow::EnterHints);
  640.  
  641.   frame->Insert(*cb, TDecoratedFrame::Top);
  642.  
  643.   MainWindow = frame;
  644.   MainWindow->SetIcon(this, IC_OWLDIAG);
  645.  
  646.   // Construct a status bar & insert it at the bottom
  647.   //
  648.   TStatusBar *pS = new TStatusBar(0, TGadget::Recessed,
  649.     TStatusBar::CapsLock | TStatusBar::NumLock | TStatusBar::ScrollLock);
  650. //  pS->Attr.Id = CM_STATUSBAR;
  651.   frame->Insert(*pS, TDecoratedFrame::Bottom);
  652.  
  653. //  EnableCtl3d(true);
  654. }
  655.  
  656. //
  657. //  Entry point
  658. //
  659.  
  660. int
  661. OwlMain(int /*argc*/, char* /*argv*/ [])
  662. {
  663.   ::SetMessageQueue(32);
  664.   return TOwlDiagApp().Run();
  665. }
  666.